﻿using System;
using System.IO;
using System.Text;
using Log;

namespace RegLog
{
    /// <summary>
    /// Classe para registros de logs em arquivo de texto.
    /// </summary>
    public class LogArquivoTexto : ILog
    {
        /// <summary>
        /// Informa se o arquivo de log existente será ou não substituido.
        /// </summary>
        public bool SubstituirArquivo { get; set; }
        /// <summary>
        /// Nome do arquivo de log a ser utilizado.
        /// </summary>
        public string NomeArquivo { get; set; }

        private string caminhoArquivo;
        /// <summary>
        /// Caminho completo do repositório do arquivo de log.
        /// </summary>
        public string CaminhoArquivo 
        { 
            get 
            {
                return caminhoArquivo; 
            }
            set
            {
                caminhoArquivo = value;
                if (caminhoArquivo.LastIndexOf('\\') < caminhoArquivo.Length -1)
                    caminhoArquivo += "\\";
            } 
        }

        /// <summary>
        /// Contrutor que define os dados do arquivo de log e seu método de gravação
        /// </summary>
        /// <param name="caminhoArquivo">Caminho onde o arquivo de log está gravado ou será criado.</param>
        /// <param name="nomeArquivo">Nome para o arquivo de log.</param>
        /// <param name="substituirArquivo">Define se o arquivo de log será substituido ou apenas incrementado. Utilize true para substituir o arquivo, o contrário para adicinoar registros ao arquivo existente.</param>
        public LogArquivoTexto(string caminhoArquivo, string nomeArquivo, bool substituirArquivo)
        {
            NomeArquivo = nomeArquivo;
            CaminhoArquivo = caminhoArquivo;
            SubstituirArquivo = substituirArquivo;
            if (!Directory.Exists(CaminhoArquivo)) Directory.CreateDirectory(CaminhoArquivo);
        }

        /// <summary>
        /// Evento de registro do log em arquivo texto
        /// </summary>
        /// <param name="sender">Objeto de chamada do log.</param>
        /// <param name="e">Conteúdo do log para o LogEventos</param>
        /// <param name="ret">Utilizado para retornar o resultado da execução à aplicação chamadora.</param>
        public void Log(object sender, EventosLogEventArgs e, out int ret)
        {
            string logConteudo = string.Format("Data/Hora: {0}{3}Tipo do Log: {1}{3}Descrição: {2}{3}Dados da Exceção: {3}\tMensagem: {4}{3}\tSource: {5}{3}\tStackTrace: {6}{3}\tTargetSite: {7}{3}{3}", 
                e.DataHora, 
                e.TipoLogString, 
                e.Descricao, 
                Environment.NewLine,                
                e.Exception.Message, 
                e.Exception.Source, 
                e.Exception.StackTrace, 
                e.Exception.TargetSite);
            if (!string.IsNullOrEmpty(CaminhoArquivo) && !string.IsNullOrEmpty(NomeArquivo))
            {
                try
                {
                    string arquivo = CaminhoArquivo + NomeArquivo;
                    if (SubstituirArquivo && File.Exists(arquivo)) File.Delete(arquivo);
                    var modoGravacao = SubstituirArquivo ? FileMode.CreateNew : FileMode.Append;
                    var modoAcesso = modoGravacao == FileMode.Append ? FileAccess.Write : FileAccess.ReadWrite;
                    var log = new FileStream(arquivo, modoGravacao, modoAcesso);
                    var escrita = new StreamWriter(log, Encoding.Default);
                    escrita.Flush();
                    escrita.Write(logConteudo);
                    escrita.Flush();
                    escrita.Close();
                    log.Close();
                    ret = 0;
                }
                catch (Exception ex)
                {
                    ret = -1;
                    throw ex;
                }
            }
            else
            {
                ret = -1;
                throw new Exception("Arquivo de log não encontrado");
            }
        }
    }
}